package highscore;

import java.util.Vector;
import utils.Order;
import utils.PlayerDoesNotExistException;

/**
 * @author Skomakar'n Swedman
 *
 * Uses functionality from the class Order to organize the items in a highscore list.
 */

public class HighscoreOrganizer
{
    private Highscore highscore;

    /**
     * Default constructor.
     */

    public HighscoreOrganizer()
    {
        this(null);
    }

    /**
     * @param highscore The highscore to modify.
     * 
     * Constructor.
     */

    public HighscoreOrganizer(Highscore highscore)
    {
        if (highscore == null)
            this.highscore = new Highscore();
        else
            this.highscore = highscore;
    }

    /**
     * Order by name ascending.
     */

    public void orderByNameAscending()
    {
        // Check if there is any reason to try to order
        // the items at all (if there are more than one).
        if (highscore.getRowCount() > 1)
        {
            // This variables checks how many of the items that were in order.
            for (int i = 0; i < highscore.getRowCount() - 1; i ++)
            {
                // Check if the next two items are in order.
                if (!inOrder(highscore.getRowAt(i).getName(),highscore.getRowAt(i + 1).getName()))
                {
                    Order.changeVectorPosition(highscore.getAllRows(),i,i + 1);
                    orderByNameAscending();
                }
            }
        }
    }

    /**
     * Order by name descending.
     */

    public void orderByNameDescending()
    {
        orderByNameAscending();
        Order.reverseVector(highscore.getAllRows());
    }

    /**
     * Order by level ascending.
     */

    public void orderByLevelAscending()
    {
        // Check if there is any reason to try to order
        // the items at all (if there are more than one).
        if (highscore.getRowCount() > 1)
        {
            for (int i = 0; i < highscore.getRowCount() - 1; i ++)
            {
                // Check if the next two items are in order.
                if (highscore.getRowAt(i).getLevel() > highscore.getRowAt(i + 1).getLevel())
                {
                    Order.changeVectorPosition(highscore.getAllRows(),i,i + 1);
                    orderByLevelAscending();
                }
            }
        }
    }

    /**
     * Order by level descending.
     */

    public void orderByLevelDescending()
    {
        orderByLevelAscending();
        Order.reverseVector(highscore.getAllRows());
    }

    /**
     * Order by score ascending.
     */

    public void orderByScoreAscending()
    {
        // Check if there is any reason to try to order
        // the items at all (if there are more than one).
        if (highscore.getRowCount() > 1)
        {
            for (int i = 0; i < highscore.getRowCount() - 1; i ++)
            {
                // Check if the next two items are in order.
                if (highscore.getRowAt(i).getScore() > highscore.getRowAt(i + 1).getScore())
                {
                    Order.changeVectorPosition(highscore.getAllRows(),i,i + 1);
                    orderByScoreAscending();
                }
            }
        }
    }

    /**
     * Order by score descending.
     */

    public void orderByScoreDescending()
    {
        orderByScoreAscending();
        Order.reverseVector(highscore.getAllRows());
    }

    /**
     * Order by date ascending.
     */

    public void orderByDateAscending()
    {
        // Check if there is any reason to try to order
        // the items at all (if there are more than one).
        if (highscore.getRowCount() > 1)
        {
            for (int i = 0; i < highscore.getRowCount() - 1; i ++)
            {
                // Check if the next two items are in order.
                if (highscore.getRowAt(i).getDate().getTime() > highscore.getRowAt(i + 1).getDate().getTime())
                {
                    Order.changeVectorPosition(highscore.getAllRows(),i,i + 1);
                    orderByDateAscending();
                }
            }
        }
    }

    /**
     * Order by date descending.
     */

    public void orderByDateDescending()
    {
        orderByDateAscending();
        Order.reverseVector(highscore.getAllRows());
    }

    /**
     * Checks whether two strings are in alphabetical order.
     *
     * @param string1 The first string.
     * @param string2 The second string.
     * @return Whether the first string is before the second string in alphabetical order.
     */
    private boolean inOrder(String string1,String string2)
    {
        int first = 0;

        if (string1.matches(string2))
            first = 0;

        int length = (string1.length() < string2.length()) ? string1.length() : string2.length();

        for (int i = 0; i < length; i ++)
        {
            first = 2;

            if ((int)string1.charAt(i) < (int)string2.charAt(i))
            {
                first = 0;
                break;
            }
            else if ((int)string1.charAt(i) > (int)string2.charAt(i))
            {
                first = 1;
                break;
            }
        }

        if (first == 2)
            first = (string1.length() < string1.length()) ? 0 : 1;

        return (first == 0);
    }

    public HighscoreRow getPlayersBestScore(String player) throws PlayerDoesNotExistException
    {
		orderByScoreDescending();
		for (int i = 0; i < highscore.getRowCount(); i++)
		{
			HighscoreRow row = highscore.getRowAt(i);
			if (row.getName().equalsIgnoreCase(player))
			{
			return row;
			}
		}
		throw new PlayerDoesNotExistException("Couldn't find " + player + " in the highscore");
    }
}
